home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
Font.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-27
|
8KB
|
389 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "Font.h"
#include "Class.h"
#include "Error.h"
#include "String.h"
#include "WindowSystem.h"
#include "ObjArray.h"
#include "OrdColl.h"
#include "Env.h"
#include "Math.h"
Font *gSysFont,
*gApplFont,
*gFixedFont;
class FontManager *gFontManager;
bool freal;
static Symbol FontNames[12];
//---- Font --------------------------------------------------------------------
NewMetaImpl(Font,Object, (TA(cw), TE(face), T(size), T(ils), T(ht), T(bs), T(width), TP(ff)));
Font *new_Font(GrFont font, int size, GrFace face)
{
return gFontManager->MapFont(font, size, face);
}
Font *new_Font(GrFont font, int size, GrFace face, bool)
{
freal= TRUE;
Font *fp= gFontManager->MapFont(font, size, face);
freal= FALSE;
return fp;
}
Font::Font(FontFamily *f, short ps, GrFace fc)
{
ff= f;
size= ps;
face= fc;
if (ff)
ff->fmap->Add(this);
}
Font *Font::WithFace(GrFace fc)
{
return gFontManager->MapFont(Fid(), size, fc);
}
Font *Font::WithSize(int sz)
{
return gFontManager->MapFont(Fid(), sz, face);
}
int Font::Width(register byte *s, register int l)
{
register int w= 0;
if (s) {
if (l < 0) {
while(*s)
w+= cw[*s++];
} else {
while(--l >= 0)
w+= cw[*s++];
}
}
return w;
}
int Font::MaxWidth(int l)
{
if (width < 0) {
register int i;
width= 0;
for (i= 0; i< 255; i++)
width= Math::Max((u_short)width, cw[i]);
}
return l*width;
}
Rectangle Font::BBox(register byte *s, register int l)
{
register int w= 0;
if (s == 0)
return gRect0;
if (l < 0) {
while(*s)
w+= cw[*s++];
} else {
while(--l >= 0)
w+= cw[*s++];
}
return Rectangle(0, ht, w, ht+bs);
}
Metric Font::GetMetric(register byte *s, register int l)
{
register int w= 0;
if (s == 0)
return Metric(0);
if (l < 0) {
while(*s)
w+= cw[*s++];
} else {
while(--l >= 0)
w+= cw[*s++];
}
return Metric(w, Ascender()+Descender(), Ascender());
}
Metric Font::GetMetric(byte c)
{
return Metric(Width(c), Ascender()+Descender(), Ascender());
}
Rectangle Font::BBox(register byte c, Point pos)
{
return Rectangle(pos.x, pos.y-Ascender(), Width(c), Spacing());
}
Point Font::AdjustString(register byte *s, Point p, GrVAdjust va, GrHAdjust ha)
{
register int w= 0;
if (ha) {
if (s)
while(*s)
w+= cw[*s++];
switch (ha) {
case eAdjHRight:
p.x-= w;
break;
case eAdjHCenter:
p.x-= w/2;
break;
default:
break;
}
}
switch (va) {
case eAdjVBottom:
p.y-= bs;
break;
case eAdjVCenter:
p.y+= (ht-bs)/2;
break;
case eAdjVTop:
p.y+= ht;
break;
case eAdjVBase:
break;
}
return p;
}
DevBitmap *Font::CharAsBitmap(byte, Point*)
{
return 0;
}
char *Font::AsString()
{
return form("%s.%d.%s", Name(), Size(), gFontManager->StyleString(Face()));
}
u_long Font::Hash()
{
return (u_long) Fid();
}
bool Font::IsEqual(Object *op)
{
return op->IsKindOf(Font) && ((Font*)op)->Size() == Size()
&& ((Font*)op)->Face() == Face();
}
OStream& Font::PrintOn(OStream &s)
{
return s << FontNames[Fid()] SP << Size() SP << (int)Face() SP;
}
Object *Font::ReadAndMap(IStream &s)
{
int size;
GrFace face;
Symbol name;
s >> name >> size >> Enum(face);
return new_Font(gFontManager->NameToId(name.AsString()), size, face);
}
//---- FontManager -------------------------------------------------------------
NewMetaImpl(FontManager,Object, (TP(fmap)));
FontManager::FontManager()
{
fmap= new ObjArray;
FontNames[0]= Symbol("Times");
FontNames[1]= Symbol("Helvetica");
FontNames[2]= Symbol("Courier");
FontNames[3]= Symbol("Symbol");
FontNames[4]= Symbol("Chicago");
FontNames[5]= Symbol("Avantgarde");
FontNames[6]= Symbol("Bookman");
FontNames[7]= Symbol("Schoolbook");
FontNames[8]= Symbol("NarrowHelvetica");
FontNames[9]= Symbol("Palatino");
FontNames[10]= Symbol("ZapfChancery");
FontNames[11]= Symbol("ZapfDingbats");
}
FontManager::~FontManager()
{
if (fmap) {
fmap->FreeAll();
SafeDelete(fmap);
}
}
bool FontManager::Init()
{
int size= Env::GetValue("Font.Size", 12);
GrFont fid= gFontManager->NameToId(Env::GetValue("Font.Sys", "Chicago"));
gSysFont= new_Font(fid, size);
fid= gFontManager->NameToId(Env::GetValue("Font.Appl", "Helvetica"));
gApplFont= new_Font(fid, size);
fid= gFontManager->NameToId(Env::GetValue("Font.Fixed", "Courier"));
gFixedFont= new_Font(fid, size);
return FALSE;
}
FontFamily *FontManager::MapFamily(GrFont fid)
{
FontFamily *fm;
if ((fm= (FontFamily*) fmap->At(fid)) == 0) {
if (fid < eFontTimes || fid > eFontDingbats)
return (FontFamily*) fmap->At(eFontChicago);
fmap->AtPutAndExpand(fid, fm= new FontFamily(fid));
}
return fm;
}
Font *FontManager::MapFont(GrFont fid, int size, GrFace face)
{
return MapFamily(fid)->MapSizeFace(size, face);
}
Font *FontManager::MakeFont(FontFamily*, int, GrFace, bool)
{
return 0;
}
Font *FontManager::ScaleFont(FontFamily *ff, int size, GrFace face)
{
Font *f;
int facebit;
if (face != eFacePlain) {
for (facebit= eFaceShadow; facebit; facebit >>= 1) {
if (face & facebit) {
face= (GrFace) (face & ~facebit);
return ff->MapSizeFace(size, face);
}
}
}
for (int i= 6; i < 24; i++) {
if ((size-i > 6) && (f= ff->MapSizeFace2(size-i, face)))
return f;
if ((size+i > 24) && (f= ff->MapSizeFace2(size+i, face)))
return f;
}
return 0;
}
GrFont FontManager::NameToId(char *fontname)
{
Symbol name(fontname);
for (int i= 0; i < sizeof(FontNames) / sizeof(FontNames[0]); i++)
if (FontNames[i] == name)
return (GrFont)i;
return (GrFont)-1;
}
char *FontManager::IdToName(GrFont fid)
{
if (fid >= 0 && fid < sizeof(FontNames) / sizeof(FontNames[0]))
return FontNames[fid].AsString();
return 0;
}
char *FontManager::StyleString(GrFace face)
{
static char buf[20];
char *cp= buf;
if (face == eFacePlain)
*cp++= 'r';
else {
if (face & eFaceBold)
*cp++= 'b';
if (face & eFaceItalic)
*cp++= 'i';
if (face & eFaceUnderline)
*cp++= 'u';
if (face & eFaceOutline)
*cp++= 'o';
if (face & eFaceShadow)
*cp++= 's';
}
*cp= '\0';
return buf;
}
void FontManager::CollectParts(class Collection *col)
{
col->Add(fmap);
}
//---- FontFamily --------------------------------------------------------------
NewMetaImpl(FontFamily,Object, (TE(fid), TB(fixed), TP(fmap)));
FontFamily::FontFamily(GrFont f)
{
fid= f;
fmap= new OrdCollection;
}
FontFamily::~FontFamily()
{
if (fmap) {
fmap->FreeAll();
SafeDelete(fmap);
}
}
char *FontFamily::Name()
{
return FontNames[fid].AsString();
}
Font *FontFamily::MapSizeFace2(int size, GrFace face, bool dflt)
{
Iter next(fmap);
register Font *fp;
// if (! freal) {
while (fp= (Font*) next())
if (fp->Size() == size && fp->Face() == face)
return fp;
// }
freal= FALSE;
return gFontManager->MakeFont(this, size, face, dflt);
}
Font *FontFamily::MapSizeFace(int size, GrFace face)
{
Font *f;
if (f= MapSizeFace2(size, face))
return f;
if (f= gFontManager->ScaleFont(this, size, face))
return f;
return MapSizeFace2(0, face, TRUE);
}
void FontFamily::InspectorId(char *buf, int bufSize)
{
strncpy(buf, Name(), bufSize);
}
void FontFamily::CollectParts(class Collection *col)
{
col->Add(fmap);
}